home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / OSK_ASY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-23  |  8.5 KB  |  431 lines

  1. #ifdef OSK
  2. /* OS- and machine-dependent stuff for asynch ports on OS-9
  3.  * Copyright 1993 Brian A. Lantz, KO4KS
  4.  */
  5. #include "global.h"
  6. #include <dos.h>
  7. #include "mbuf.h"
  8. #include "proc.h"
  9. #include "iface.h"
  10. #include "n8250.h"
  11. #include "asy.h"
  12. #include "devparam.h"
  13. #include "pc.h"
  14. #include <sgstat.h>
  15. #include <modes.h>
  16.  
  17. #if !defined(_lint)
  18. static char rcsid[] OPTIONAL = "$Id: osk_asy.c,v 1.9 1996/12/23 22:44:37 root Exp root $";
  19. #endif
  20.  
  21. extern int _gs_opt();
  22. extern void _ss_opt();
  23.  
  24. #define ASY_MAX 5
  25. #define PARAM_SPEED 10
  26.  
  27. static void asy_tx (int dev,void *p1,void *p2);
  28.  
  29. struct asy Asy[ASY_MAX];
  30.  
  31. /* Initialize asynch port "dev" */
  32. int
  33. asy_init(dev,ifp,arg1,arg2,bufsize,trigchar,monitor,speed,force,triglevel)
  34. int dev;
  35. struct iface *ifp;
  36. char *arg1,*arg2;    /* Attach args for address and vector */
  37. int16 bufsize;
  38. int trigchar;
  39. char monitor;
  40. long speed;
  41. int force;
  42. int triglevel;
  43. {
  44. register unsigned base;
  45. register struct fifo *fp;
  46. register struct asy *ap;
  47. char termname[8], prefix[4];
  48. char *ifn;
  49. struct sgbuf sbuf;
  50. short *nm = (short *) prefix;
  51.         
  52.         ap = &Asy[dev];
  53.         ap->iface = ifp;
  54.  
  55.     ap->addr = atoi(arg2);   /* hex string for device name prefix */
  56.     *nm = htoi(arg1);   /* hex-coded ASCII for name prefix "t" etc */
  57.     if (!prefix[0])
  58.         prefix[0] = 't';
  59.  
  60.     /* Set up receiver FIFO */
  61.     fp = &ap->fifo;
  62.     fp->buf = mallocw(bufsize);
  63.     fp->bufsize = bufsize;
  64.     fp->wp = fp->rp = fp->buf;
  65.     fp->cnt = 0;
  66.     fp->hiwat = 0;
  67.     fp->overrun = 0;
  68.     base = ap->addr;
  69.     ap->trigchar = trigchar;
  70.  
  71.         sprintf (termname, "/%s%d", prefix, base);
  72.         if ((ap->vec = (unsigned) fopen(termname, "a+")) == 0) {
  73.             tprintf("asy%d: Open failed.\n", dev);
  74.             return -1;
  75.         }
  76.         setbuf ((FILE *) ap->vec, NULL);
  77.     asy_speed(dev,speed);
  78.  
  79.         _gs_opt(fileno((FILE *)ap->vec), &sbuf);
  80.         sbuf.sg_case = 0;
  81.         sbuf.sg_backsp = 0;
  82.         sbuf.sg_delete = 0;
  83.         sbuf.sg_echo = 0;
  84.         sbuf.sg_alf = 0;
  85. /*        sbuf.sg_nulls = 0;    */
  86.         sbuf.sg_pause = 0;
  87.         sbuf.sg_page = 0;
  88.         sbuf.sg_bspch = 0;
  89.         sbuf.sg_dlnch = 0;
  90.         sbuf.sg_eorch = 0;
  91.         sbuf.sg_eofch = 0;
  92.         sbuf.sg_rlnch = 0;
  93.         sbuf.sg_dulnch = 0;
  94.         sbuf.sg_psch = 0;
  95.         sbuf.sg_kbich = 0;
  96.         sbuf.sg_kbach = 0;
  97.         sbuf.sg_bsech = 0;
  98.         sbuf.sg_bellch = 0;
  99.         sbuf.sg_xon = 0;
  100.         sbuf.sg_xoff = 0;
  101. /*        sbuf.sg_tabcr = 0;
  102.         sbuf.sg_tabsiz = 0;    */
  103.         _ss_opt(fileno((FILE *)ap->vec), &sbuf);
  104.  
  105.     ifp->txproc = newproc( ifn = if_name(ifp," tx"),
  106.             256, asy_tx, dev, ifp, NULL, 0);
  107.     free(ifn);
  108.  
  109.         return 0;
  110. }
  111.  
  112.  
  113. int
  114. asy_stop(ifp)
  115. struct iface *ifp;
  116. {
  117.     register unsigned base;
  118.     register struct asy *ap;
  119.  
  120.     ap = &Asy[ifp->dev];
  121.     free(ap->fifo.buf);
  122.     fclose ((FILE *)ap->vec);
  123.     ap->vec = 0;
  124.     return 0;
  125. }
  126.  
  127.  
  128. /* Asynchronous line I/O control */
  129. int32
  130. asy_ioctl(ifp,cmd,set,val)
  131. struct iface *ifp;
  132. int cmd;
  133. int set;
  134. int32 val;
  135. {
  136. struct asy *ap = &Asy[ifp->dev];
  137. int16 base = ap->addr;
  138.  
  139.     switch(cmd){
  140.     case PARAM_SPEED:
  141.         if(set)
  142.             asy_speed(ifp->dev,val);
  143.         return ap->speed;
  144. #ifdef notyet
  145.     case PARAM_DTR:
  146.         if(set) {
  147.             writebit(base+MCR,MCR_DTR,(int)val);
  148.             ap->dtr_usage = (val) ? MOVED_UP : MOVED_DOWN;
  149.         }
  150.         return (inportb(base+MCR) & MCR_DTR) ? TRUE : FALSE;
  151.     case PARAM_RTS:
  152.         if(set) {
  153.             writebit(base+MCR,MCR_RTS,(int)val);
  154.             ap->rts_usage = (val) ? MOVED_UP : MOVED_DOWN;
  155.         }
  156.         return (inportb(base+MCR) & MCR_RTS) ? TRUE : FALSE;
  157.     case PARAM_DOWN:
  158.         clrbit(base+IER,(char)IER_DAV);
  159.         clrbit(base+MCR,MCR_RTS);
  160.         clrbit(base+MCR,MCR_DTR);
  161.         ap->rts_usage = MOVED_DOWN;
  162.         ap->dtr_usage = MOVED_DOWN;
  163.         return FALSE;
  164.     case PARAM_UP:
  165.         setbit(base+IER,(char)IER_DAV);
  166.         setbit(base+MCR,MCR_RTS);
  167.         setbit(base+MCR,MCR_DTR);
  168.         ap->rts_usage = MOVED_UP;
  169.         ap->dtr_usage = MOVED_UP;
  170.         return TRUE;
  171.     case PARAM_BLIND:
  172.         setbit(base+IER,(char)IER_DAV);
  173.         ap->rlsd_line_control = IGNORED;
  174.  
  175.         if ( ap->monitor != NULL ) {
  176.             killproc( ap->monitor );
  177.             ap->monitor = NULL;
  178.         }
  179.  
  180.         /* can't see what we are doing, so pretend we're up */
  181.         if ( ifp->iostatus != NULL ) {
  182.             (*ifp->iostatus)(ifp, PARAM_UP, 0L);
  183.         }
  184.         return TRUE;
  185. #endif
  186.     };
  187.     return -1;
  188. }
  189.  
  190.  
  191. /* Set asynch line speed */
  192. int
  193. asy_speed(dev,speed)
  194. int dev;
  195. long speed;
  196. {
  197.     return 0;
  198. }
  199.  
  200.  
  201. /* Start transmission of a buffer on the serial transmitter */
  202. static void
  203. asy_output(dev,buf,cnt)
  204. int dev;
  205. char *buf;
  206. unsigned short cnt;
  207. {
  208. struct asy *asyp;
  209.  
  210.     if(dev < 0 || dev >= ASY_MAX)
  211.         return;
  212.     asyp = &Asy[dev];
  213.     if(asyp->iface == NULLIF)
  214.         return;
  215.     asyp->txints++;
  216.     asyp->txchar += cnt;
  217.     fwrite (buf, 1, cnt, (FILE *)asyp->vec);
  218. }
  219.  
  220.  
  221. /* Blocking read from asynch line
  222.  * Returns character or -1 if aborting
  223.  * Returns -2 (CD_DOWN) if carrier checking is on and dropped
  224.  */
  225. int
  226. get_asy(dev)
  227. int dev;
  228. {
  229. char i_state;
  230. register struct fifo *fp;
  231. char c;
  232.  
  233.     fp = &Asy[dev].fifo;
  234.  
  235.     while(fp->cnt == 0){
  236.         if(kwait(fp) != 0)
  237.             return -1;
  238.     }
  239.     fp->cnt--;
  240.  
  241.     c = *fp->rp++;
  242.     if(fp->rp >= &fp->buf[fp->bufsize])
  243.         fp->rp = fp->buf;
  244.  
  245.     return uchar(c);
  246. }
  247.  
  248. /* Process received characters */
  249. static int
  250. asyrxint(asyp)
  251. struct asy *asyp;
  252. {
  253. register struct fifo *fp;
  254. char c,lsr;
  255. int cnt = 0, doneone = 0;
  256. int trigseen = FALSE;
  257.  
  258.     if (!asyp->vec)
  259.         return cnt;
  260.     fp = &asyp->fifo;
  261.     for(;;){
  262.         if(_gs_rdy(fileno((FILE *)asyp->vec)) > 0){
  263.             asyp->rxchar++;
  264.             doneone = 1;
  265.             fread (&c, 1, 1, (FILE *)asyp->vec);
  266.             if(asyp->trigchar == uchar(c))
  267.                 trigseen = TRUE;
  268.             /* If buffer is full, we have no choice but
  269.              * to drop the character
  270.              */
  271.             if(fp->cnt != fp->bufsize){
  272.                 *fp->wp++ = c;
  273.                 if(fp->wp >= &fp->buf[fp->bufsize])
  274.                     /* Wrap around */
  275.                     fp->wp = fp->buf;
  276.                 fp->cnt++;
  277.                 if(fp->cnt > fp->hiwat)
  278.                     fp->hiwat = fp->cnt;
  279.                 cnt++;
  280.             } else
  281.                 fp->overrun++;
  282.         } else
  283.             break;
  284.     }
  285.     if(cnt > asyp->rxhiwat)
  286.         asyp->rxhiwat = cnt;
  287.     if(trigseen)
  288.         ksignal(fp,1);
  289.     if (doneone)
  290.         asyp->rxints++;
  291.     return cnt;
  292. }
  293.  
  294.  
  295. /* Poll the asynch input queues; called on every clock tick.
  296.  * This helps limit the interrupt ring buffer occupancy when long
  297.  * packets are being received.
  298.  */
  299. void
  300. asytimer()
  301. {
  302. register struct asy *asyp;
  303. register struct fifo *fp;
  304. register int i;
  305.  
  306.     for(i=0;i<ASY_MAX;i++){
  307.         asyp = &Asy[i];
  308.         asyrxint (asyp);
  309.         fp = &asyp->fifo;
  310.         if(fp->cnt != 0)
  311.             ksignal(fp,1);
  312. #ifdef notyet TIPMAIL
  313.         if (Tipsuspended[i].ifp)    {
  314.             if (!carrier_detect(i))    {
  315.                 char buf[40];
  316.                 sprintf (buf, "start tip %s %s %d\n", Tipsuspended[i].ifp->name, (Tipsuspended[i].modem) ? "m" : "t", Tipsuspended[i].timeout);
  317.                 cmdparse(Cmds,buf,NULL);
  318.                 Tipsuspended[i].ifp = 0;
  319.                 Tipsuspended[i].modem = 0;
  320.                 Tipsuspended[i].timeout = 0;
  321.             }
  322.         }
  323. #endif
  324.     }
  325. }
  326.  
  327.  
  328. int
  329. doasystat(argc,argv,p)
  330. int argc;
  331. char *argv[];
  332. void *p;
  333. {
  334. register struct asy *asyp;
  335.  
  336.     for(asyp = Asy;asyp < &Asy[ASY_MAX];asyp++){
  337.         if(asyp->iface == NULLIF)
  338.             continue;
  339.  
  340.         tprintf("%s:",asyp->iface->name);
  341.         if(asyp->trigchar != -1)
  342.             tprintf(" [trigger 0x%02x]",asyp->trigchar);
  343. #ifdef notyet
  344.         switch (asyp->cts_flow_control) {
  345.         case MOVED_DOWN:
  346.         case MOVED_UP:
  347.             tprintf(" [cts flow control]");
  348.             break;
  349.         };
  350.         switch (asyp->rlsd_line_control) {
  351.         case MOVED_DOWN:
  352.         case MOVED_UP:
  353.             tprintf(" [rlsd line control]");
  354.             break;
  355.         case IGNORED:
  356.             tprintf(" [blind]");
  357.             break;
  358.         };
  359. #endif
  360.         tprintf(" %lu bps\n",asyp->speed);
  361.  
  362.         tprintf(" RX: %lu int, %lu chr, %lu hw over, %lu hw hi\n",
  363.             asyp->rxints,
  364.             asyp->rxchar,
  365.             asyp->overrun,
  366.             asyp->rxhiwat);
  367.         asyp->rxhiwat = 0;
  368.         if(tprintf(" TX: %lu int, %lu chars, %u q\n",
  369.             asyp->txints, asyp->txchar, len_q(asyp->sndq)) == EOF)
  370.             break;
  371.     }
  372.     return 0;
  373. }
  374.  
  375.  
  376. /* Send a message on the specified serial line */
  377. int
  378. asy_send(dev,bp)
  379. int dev;
  380. struct mbuf *bp;
  381. {
  382.     if(dev < 0 || dev >= ASY_MAX)
  383.         return -1;
  384.     enqueue(&Asy[dev].sndq,bp);
  385.     return 0;
  386. }
  387.  
  388.  
  389.  
  390. /* Serial transmit process, common to all protocols */
  391. static void
  392. asy_tx(dev,p1,p2)
  393. int dev;
  394. void *p1;
  395. void *p2;
  396. {
  397. register struct mbuf *bp;
  398. struct asy *asyp;
  399.  
  400.     asyp = &Asy[dev];
  401.  
  402.     for(;;){
  403.         /* Fetch a buffer for transmission */
  404.         while(asyp->sndq == NULLBUF)
  405.             kwait(&asyp->sndq);
  406.  
  407.         bp = dequeue(&asyp->sndq);
  408.  
  409.         while(bp != NULLBUF){
  410.             /* Start the transmitter */
  411.             asy_output(dev,bp->data,bp->cnt);
  412.  
  413.             /* Now do next buffer on chain */
  414.             bp = free_mbuf(bp);
  415.         }
  416.     }
  417. }
  418.  
  419.  
  420. int
  421. carrier_detect(dev)
  422. int dev;
  423. {
  424.     return 1;
  425. }
  426.  
  427.  
  428.  
  429. #endif /* OSK */
  430.  
  431.